package client;

import interfaces.ClientITF;
import interfaces.ServeurITF;

import java.rmi.RemoteException;
import java.rmi.NotBoundException;

import java.awt.GridLayout;
import java.awt.BorderLayout;
import java.awt.Dimension;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JTextField;
import javax.swing.JOptionPane;

import java.awt.event.ActionListener; 
import java.awt.event.ActionEvent;

public class ClientInterface extends JFrame implements ActionListener
{
	// Boite de dialogue pour se connecter à un serveur
	public class ConnectDialog extends JDialog
	{
		private boolean valid;
	
		private JPanel panel_input;
		private JPanel panel_host;
		private JPanel panel_port;
		private JPanel panel_control;
		
		private JLabel label_host;
		private JLabel label_port;
		
		private JTextField text_host;
		private JTextField text_port;
		
		private JButton button_ok;
		private JButton button_cancel;
		
		public ConnectDialog(JFrame parent, String title, boolean modal)
		{
			// On appelle le constructeur de JDialog correspondant
			super(parent, title, modal);
			
			// Paramètres du dialogue
			this.setLocationRelativeTo(parent);
			this.setResizable(false);
			this.setSize(250, 100);
			
			// Panels
			panel_input   = new JPanel(new GridLayout(2,1));
			panel_host    = new JPanel();
			panel_port    = new JPanel();
			panel_control = new JPanel(new GridLayout(1,2));
			
			// Labels
			label_host = new JLabel("Address : ");
			label_port = new JLabel("Port    : ");
			
			// Zones de texte
			text_host = new JTextField("localhost");
			text_host.setPreferredSize(new Dimension(100, 25));
			text_port = new JTextField();
			text_port.setPreferredSize(new Dimension(100, 25));
			
			panel_host.add(label_host);
			panel_host.add(text_host);
			panel_port.add(label_port);
			panel_port.add(text_port);
			
			panel_input.add(panel_host);
			panel_input.add(panel_port);
			
			// Boutons
			button_ok     = new JButton("OK");
			button_cancel = new JButton("Annuler");
			
			// Actions sur les boutons
			button_ok.addActionListener(
				new ActionListener()
				{
					public void actionPerformed(ActionEvent arg0) {
						valid = true;
						setVisible(false);
					}			
				}
			);
			
			button_cancel.addActionListener(
				new ActionListener()
				{
					public void actionPerformed(ActionEvent arg0) {
						valid = false;
						setVisible(false);
					}			
				}
			);
			
			panel_control.add(button_ok);
			panel_control.add(button_cancel);
		
			// Panel
			this.getContentPane().add(panel_input, BorderLayout.CENTER);
			this.getContentPane().add(panel_control, BorderLayout.SOUTH);
		}
		
		// Affichage de la boîte de dialogue
		public String showConnectDialog()
		{
			this.setVisible(true);
			
			if (valid)
			{
				return text_host.getText() + ":" + text_port.getText();
			}
			else
			{
				return null;
			}
		}
	}
	
	public ClientITF client;
	public ServeurITF server;

	private JPanel  panel;
	private JButton button_connect;
	private JButton button_infos;
	private JButton button_video;
	private JButton button_quit;

	public ClientInterface(ClientITF _client)
	{
		client = _client;
		
		// Paramètres de la fenêtre
		this.setTitle("Client");
		this.setSize(200, 200);
		this.setLocationRelativeTo(null);
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		// Panel
		panel = new JPanel(new GridLayout(4, 1));
		
		// Boutons
		button_connect = new JButton("Connexion");
		button_infos   = new JButton("Informations serveur");
		button_video   = new JButton("Regarder la vidéo");
	    button_quit    = new JButton("Déconnexion");
	    
	    // Action sur les boutons
	    button_connect.addActionListener(this);
	    button_infos  .addActionListener(this);
	    button_video  .addActionListener(this);
	    button_quit   .addActionListener(this);
	    
	    // Au début on est pas connecté, on désactive certains boutons
	    button_infos.setEnabled(false);
	    button_video.setEnabled(false);
	    button_quit .setEnabled(false);
	    
	    // Boutons -> panel
	    panel.add(button_connect);
	    panel.add(button_infos);
	    panel.add(button_video);
	    panel.add(button_quit);
		
		// Panel de la fenêtre
		this.setContentPane(panel);
		
		// Affichage de la fenêtre (tant qu'à faire ...)
		this.setVisible(true);
	}
	
	public void actionPerformed(ActionEvent e)
	{
		if (e.getSource() == button_connect)    { on_button_connect(); }
		else if (e.getSource() == button_infos) { on_button_infos(); }
		else if (e.getSource() == button_video) { on_button_video(); }
		else if (e.getSource() == button_quit)  { on_button_quit(); }
	}

	public void on_button_connect()
	{
		// Demande des informations de connexion
		ConnectDialog cd   = new ConnectDialog(this, "Informations serveur", true);
		String server_info = cd.showConnectDialog();
		
		// Si l'utilisateur a annulé, on se connecte pas
		if (server_info == null)
		{
			return;
		}
		
		JOptionPane info_connect = new JOptionPane();
		
		// Connexion au server
		try
		{
			server = client.connect_to(server_info);
		}
		catch (Exception e)
		{
			info_connect.showMessageDialog(null, "Connexion au serveur "+ server_info +" impossible !\n\n" + e, "Erreur", JOptionPane.ERROR_MESSAGE);
			return;
		}
		
		info_connect.showMessageDialog(null, "Connexion au serveur "+ server_info +" réussie", "Information", JOptionPane.INFORMATION_MESSAGE);
        
		try
		{
			System.out.println("* Connexion établie au serveur (id: " + client.getID() + ")");
			System.out.println("* Voisins attribués: " + client.printNeighbours());
        }
        catch (Exception e) { System.out.println(e); }
                    
		button_connect.setEnabled(false);
		button_infos  .setEnabled(true);
		button_video  .setEnabled(true);
		button_quit   .setEnabled(true);
	}
	
	public void on_button_infos()
	{
		JOptionPane info_pane = new JOptionPane();
		
		String info_str = "";
		
		try
		{
			info_str += "Adresse : "+ server.getHost() +"\n";
			info_str += "Port : "+ server.getPort() +"\n";
			
			info_str += "\nMon ID : "+ client.getID() + "\n";
			info_str += "Mes voisins : "+ client.printNeighbours() +"\n";
			
			info_str += "\nNombre de clients connectés : "+ server.nbClients() +"\n";
			info_str += "Graphe du serveur :\n" + server.printGraph();			 
		}
		catch (Exception e) { System.out.println(e); }
		
		if (info_str != "")
		{
			info_pane.showMessageDialog(null, info_str, "Informations server", JOptionPane.INFORMATION_MESSAGE);
		}
	}
	
	public void on_button_video()
	{
		JOptionPane info_pane = new JOptionPane();
		
		System.out.println("* Lancement de l'élection");
		
		try
		{	
			TokenThread t = new TokenThread(client);
			t.start();
		}
		catch (Exception e)
		{
			info_pane.showMessageDialog(null, e, "Erreur", JOptionPane.ERROR_MESSAGE);
		}
	}
	
	public void on_button_quit()
	{
		JOptionPane info_quit = new JOptionPane();
		
		try
		{
			server.disconnect(client);
		}
		catch (Exception e)
		{
			System.out.println(e);
			e.printStackTrace();
			
			info_quit.showMessageDialog(null, "Déconnexion impossible", "Erreur", JOptionPane.ERROR_MESSAGE);
			return;
		}
		
		System.out.println("* Déconnexion du serveur réussie");
		info_quit.showMessageDialog(null, "Déconnexion réussie !", "Information", JOptionPane.INFORMATION_MESSAGE);		
		
		button_connect.setEnabled(true);
		button_infos  .setEnabled(false);
	    button_video  .setEnabled(false);
	    button_quit   .setEnabled(false);
	}			
}
